package com.iwhale.sequence.redisidx.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.util.StringUtils;
import redis.clients.jedis.JedisPoolConfig;

import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;

/**
 * 弄一个redis数组
 */
@Configuration
public class RedisConfiguration {
    @Autowired
    private RedisConfig redisConfig;

    public JedisConnectionFactory connectionFactory(HostInfo hostInfo) {
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setHostName(hostInfo.getHost());
        redisStandaloneConfiguration.setPort(hostInfo.getPort());
        if (!StringUtils.isEmpty(hostInfo.getPassword())) {
            redisStandaloneConfiguration.setPassword(RedisPassword.of(hostInfo.getPassword()));
        }
        if (hostInfo.getDatabase() != null) {
            redisStandaloneConfiguration.setDatabase(hostInfo.getDatabase());
        }
        JedisConnectionFactory factory = new JedisConnectionFactory(redisStandaloneConfiguration, clientConfig());
        return factory;
    }

    public JedisClientConfiguration clientConfig() {
        JedisClientConfiguration clientConfig = JedisClientConfiguration.builder().usePooling().
                poolConfig(poolConfig()).and().
                readTimeout(Duration.ofMillis(redisConfig.getConnTimeout())).build();
        return clientConfig;
    }

    public JedisPoolConfig poolConfig() {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMinIdle(redisConfig.getMinIdle());
        poolConfig.setMaxIdle(redisConfig.getMaxIdle());
        poolConfig.setMaxTotal(redisConfig.getMaxTotal());
        poolConfig.setMaxWaitMillis(redisConfig.getMaxWaitTime());
        poolConfig.setTestOnBorrow(redisConfig.isTestOnBorrow());
        poolConfig.setTestOnReturn(redisConfig.isTestOnReturn());
        return poolConfig;
    }

    @Bean("redisTemplateMap")
    public LinkedHashMap<String, RedisTemplate> redisTemplateMap() {
        LinkedHashMap<String, RedisTemplate> redisTemplateMap = new LinkedHashMap<>();
        redisConfig.getHosts().forEach((name, host) -> {
            RedisConnectionFactory factory = connectionFactory(host);
            StringRedisTemplate template = new StringRedisTemplate(factory);
            template.setValueSerializer(new RedisSerializer<Long>() {
                @Override
                public byte[] serialize(Long aLong) throws SerializationException {
                    return String.valueOf(aLong).getBytes(StandardCharsets.UTF_8);
                }

                @Override
                public Long deserialize(byte[] bytes) throws SerializationException {
                    if(bytes==null)return 0L;
                    return Long.parseLong(new String(bytes,StandardCharsets.UTF_8));
                }
            });
            // template.setHashValueSerializer(serializer);
            // template.afterPropertiesSet();
            redisTemplateMap.put(name, template);
        });
        return redisTemplateMap;
    }

}
